﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Data.SqlClient;
using ExceptionUtils;

namespace FastDatabaseQuery
{

    public class FindHelper<T>
        where T:class
    {
        public Expression<Func<T, bool>> custompredicate { get; private set; }
        protected internal ColList<T> ColToLoad;
        public FindHelper(ColList<T> col)
        {
           
            this.ColToLoad = col;
        }

        protected virtual IQueryable<T> ObjectSetWithInclude()
        {
            return ColToLoad.SelfObjectSet;
        }
        public FindHelper<T> AddToCustomPredicate2(Expression<Func<T, bool>> pred1, Expression<Func<T, bool>> pred2, bool PutAnd)
        {
            
            AddToCustomPredicate(pred1, PutAnd);
            AddToCustomPredicate(pred2, PutAnd);
            return this;
        }
        protected void LogDebug(string message)
        {
            if (this.ColToLoad != null && this.ColToLoad._logger != null && this.ColToLoad._logger.IsDebugEnabled)
                this.ColToLoad._logger.Debug( message);
            
        }
        protected IQueryable<T> LoadFrom1PropertyQ<U>(Expression<Func<T, U>> property, U Value)
        {
            var iq = HelperExpressions.PredicateBinary(property, Value, "equal");
            //try
            {
                var ret = ObjectSetWithInclude().Where(iq);
                LogDebug(ret.ToString());
                return ret;
            }
            //catch (SqlException ex)//The provider did not return a ProviderManifestToken string
            //{
            //    if (ex.Number == 26)
            //    {
            //        throw new ExceptionNotFoundDatabase();
            //    }
            //    throw;
            //}

        }
        
        public void AddToCustomPredicate(Expression<Func<T, bool>> pred, Func<Expression, Expression, Expression> merge)
        {
            if (pred == null)
                return;

            if (custompredicate == null)
            {
                custompredicate = pred;
                return;
            }
            custompredicate = EFRebinder.Utility.AddExpression(pred, custompredicate, merge);

        }

        public IQueryable<T> LoadFindCustomPredicateQ()
        {
            var ret = ObjectSetWithInclude();
            if (custompredicate != null)
            {
                ret = ret.Where(custompredicate);
            }
            LogDebug(ret.ToString());
            return ret;
            //      return ObjectSetWithInclude().Where (custompredicate);

        }
        public void AddToCustomPredicate(Expression<Func<T, bool>> pred, bool PutAnd=true)
        {
            if (pred == null)
                return;

            if (custompredicate == null)
            {
                custompredicate = pred;
                return;
            }
            if (PutAnd)
            {
                // pred.And(custompredicate);
                custompredicate = EFRebinder.Utility.AndRebind(pred, custompredicate);
            }
            else
            {
                //pred.Or(custompredicate);
                custompredicate = EFRebinder.Utility.OrRebind(pred, custompredicate);
            }
        }
    }
}
